home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / Rkrm / Exec_Library / Interrupts / rbf.e next >
Text File  |  1995-04-05  |  5KB  |  141 lines

  1. -> rbf.e - Serial receive buffer full interrupt handler example.
  2. ->
  3. -> To receive characters, this example requires ASCII serial input at your
  4. -> Amiga's current serial hardware baud rate (i.e., 9600 after reboot, else
  5. -> last baud rate used).
  6.  
  7. -> E-Note: E does not (as of v3.1a) support Resources in the conventional way
  8. MODULE 'other/ecode',
  9.        'other/misc',
  10.        'dos/dos',
  11.        'exec/execbase',
  12.        'exec/interrupts',
  13.        'exec/nodes',
  14.        'exec/memory',
  15.        'hardware/custom',
  16.        'hardware/intbits',
  17.        'resources/misc'
  18.  
  19. ENUM ERR_NONE, ERR_BITS, ERR_ECODE, ERR_PORT, ERR_SIG
  20.  
  21. RAISE ERR_SIG IF AllocSignal()=-1
  22.  
  23. CONST BUFFERSIZE=256, NAMESIZE=32
  24. CONST ALLOCEDBUFFER=BUFFERSIZE+2
  25.  
  26. OBJECT rbfData
  27.   task
  28.   signal
  29.   bufferCount  -> E-Note: C version disagrees with Assembly handler!
  30.   charBuffer[ALLOCEDBUFFER]:ARRAY
  31.   flagBuffer[ALLOCEDBUFFER]:ARRAY
  32.   name[NAMESIZE]:ARRAY
  33. ENDOBJECT
  34.  
  35. -> E-Note: set-up "custom"
  36. DEF custom=CUSTOMADDR:PTR TO custom
  37.  
  38. PROC main() HANDLE
  39.   -> E-Note: to help with cleaning up, currentuser has been replaced by
  40.   ->         portuser and bitsuser, both initialised to non-zero
  41.   DEF allocname, rbfdata=NIL:PTR TO rbfData, portuser=-1, bitsuser=-1,
  42.       signr=-1, serdevice, rbfint=NIL:PTR TO is, priorint:PTR TO is,
  43.       priorenable, signal, exec:PTR TO execbase
  44.   -> E-Note: get the right type for execbase
  45.   exec:=execbase
  46.  
  47.   allocname:='rbf-example'
  48.  
  49.   miscbase:=OpenResource('misc.resource')
  50.  
  51.   -> Allocate the serial port registers.
  52.   IF portuser:=allocMiscResource(MR_SERIALPORT, allocname)
  53.     -> Hey! Someone's got it!
  54.     WriteF('serial hardware allocated by \s. Trying to remove it\n', portuser)
  55.  
  56.     Forbid()
  57.     IF serdevice:=FindName(exec.devicelist, portuser) THEN RemDevice(serdevice)
  58.     Permit()
  59.  
  60.     IF portuser:=allocMiscResource(MR_SERIALPORT, allocname)  -> And try again
  61.       -> E-Note: error if still allocated
  62.       Raise(ERR_PORT)
  63.     ENDIF
  64.   ENDIF
  65.  
  66.   -> Get the serial control bits.  (Give up if allocated.)
  67.   IF bitsuser:=allocMiscResource(MR_SERIALBITS, allocname) THEN Raise(ERR_BITS)
  68.   -> Got them both
  69.   WriteF('serial hardware allocated\n')
  70.  
  71.   -> Allocate a signal bit for the interrupt handler to signal us.
  72.   signr:=AllocSignal(-1)
  73.  
  74.   rbfint:=NewM(SIZEOF is, MEMF_PUBLIC OR MEMF_CLEAR)
  75.   rbfdata:=NewM(SIZEOF rbfData, MEMF_PUBLIC OR MEMF_CLEAR)
  76.   rbfdata.task:=FindTask(NIL)   -> Init rbfdata object
  77.   rbfdata.signal:=Shl(1, signr)
  78.  
  79.   rbfint.ln.type:=NT_INTERRUPT  -> Init interrupt node.
  80.   -> E-Note: copy *safely* to rbfdata.name
  81.   AstrCopy(rbfdata.name, allocname, NAMESIZE)
  82.   rbfint.ln.name:=rbfdata.name
  83.   rbfint.data:=rbfdata
  84.   rbfint.code:=eCodeIntHandler({rbfHandler})
  85.   IF rbfint.code=NIL THEN Raise(ERR_ECODE)
  86.  
  87.   -> Save state of RBF and interrupt disable it.
  88.   priorenable:=custom.intenar AND INTF_RBF
  89.   custom.intena:=INTF_RBF
  90.   IF priorint:=SetIntVector(INTB_RBF, rbfint)
  91.     WriteF('replaced the \s RBF interrupt handler\n', priorint.ln.name)
  92.   ENDIF
  93.  
  94.   WriteF('enabling RBF interrupt\n')
  95.   custom.intena:=INTF_SETCLR OR INTF_RBF
  96.  
  97.   WriteF('waiting for buffer to fill up. Use CTRL-C to break\n')
  98.   signal:=Wait(Shl(1, signr) OR SIGBREAKF_CTRL_C)
  99.  
  100.   IF signal AND SIGBREAKF_CTRL_C THEN WriteF('>break<\n')
  101.   WriteF('Character buffer contains:\n\s\n', rbfdata.charBuffer)
  102.  
  103.   custom.intena:=INTF_RBF  -> Restore previous handler.
  104.   SetIntVector(INTB_RBF, priorint)  -> Enable it if it was enabled before.
  105.   IF priorenable THEN custom.intena:=INTF_SETCLR OR INTF_RBF
  106.  
  107. EXCEPT DO
  108.   -> E-Note: these next two aren't really necessary
  109.   IF rbfdata THEN Dispose(rbfdata)
  110.   IF rbfint THEN Dispose(rbfint)
  111.   IF signr<>-1 THEN FreeSignal(signr)
  112.   -> Release serial hardware
  113.   IF bitsuser=NIL THEN freeMiscResource(MR_SERIALBITS)
  114.   IF portuser=NIL THEN freeMiscResource(MR_SERIALPORT)
  115.   -> There is no 'CloseResource()' function
  116.   SELECT exception
  117.   CASE ERR_BITS;   WriteF('Serial control already allocated by \s\n', bitsuser)
  118.   CASE ERR_ECODE;  WriteF('Ran out of memory in eCodeIntHandler()\n')
  119.   CASE ERR_PORT;   WriteF('Serial hardware already allocated by \s\n', portuser)
  120.   CASE ERR_SIG;    WriteF('Can''t allocate signal\n')
  121.   CASE "MEM";      WriteF('Ran out of memory\n')
  122.   ENDSELECT
  123. ENDPROC
  124.  
  125. -> Note - This simple handler just receives one buffer full of serial
  126. -> input data, signals main, then ignores all subsequent serial data.
  127.  
  128. -> E-Note: we could use Assembly, but we'll show how to use an E PROC
  129. -> E-Note: you get rbfint.data as first arg, interrupt flags as second
  130. PROC rbfHandler(data:PTR TO rbfData, intflags)
  131.   DEF input
  132.   IF data.bufferCount<BUFFERSIZE
  133.     input:=custom.serdatr
  134.     data.charBuffer[data.bufferCount]:=input AND $FF
  135.     data.flagBuffer[data.bufferCount]:=Shr(input, 8) AND $FF
  136.     data.bufferCount:=data.bufferCount+1
  137.     IF data.bufferCount=BUFFERSIZE THEN Signal(data.task, data.signal)
  138.   ENDIF
  139.   custom.intreq:=INTF_RBF
  140. ENDPROC
  141.